package org.ping.websocket;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.jsping.entity.Message;

import com.alibaba.fastjson.JSON;

/**
 * @author ping
 */
@ServerEndpoint("/websocket/{userId}")
public class Socket {
	/**
	 * 用来存储所有的连接用户
	 * 这个session就是和客户端的连接
	 */
	private static Map<String,Socket> socket = new HashMap<String,Socket>();
	/**
	 * 储存一个用户的消息
	 */
	private static MessageQueue magQ = MessageQueue.getInstance();
	
	public Session session = null;
	
	/**
	 * 有客户端连接成功时
	 * @param userId 客户端传递过来的userId
	 * @param session 客户端的连接
	 */
	@OnOpen
	public void onOpen(@PathParam("userId") String userId,Session session) {
		System.out.println(userId+"连接了");
		this.session = session;
		synchronized (Socket.class) {
			//每次增加一个在线用户
			socket.put(userId, this);
		}
			
		System.out.println("在线的人：");
		for(String key : socket.keySet()) {
			System.out.println(key+"-->"+socket.get(key));
		}
		//查在线好友列表！
		//查询这个用户有没有离线消息
		LinkedList<Message> res = magQ.getUserMag(Integer.valueOf(userId));
		if(res!=null) {
			
			while(res.size()>=1) {
				System.out.println(res.size());
				Message me = res.removeFirst();
				sendMess(me,this);
			}
			//magQ.del(Integer.valueOf(userId));
		}
		System.out.println("在线的人：");
		for(String key : socket.keySet()) {
			System.out.println(key+"-->"+socket.get(key));
		}
	}
	
	/**
	 * 客户端发送消息时触发
	 * @param message
	 */
	@OnMessage
	public void onMessage(@PathParam("userId") int userId,String message,Session session) {
		System.out.println("从客户端发送过来的消息"+message);
		//一个用户发送给他好友的消息
		Message ms = JSON.parseObject(message,Message.class);
		//查找这个用户在不在线，!=null就是在线
		//这个好友的id
		int fuid = ms.getFuid();
		System.out.println("好友id："+fuid);
		//设置这条消息是谁发送的
		ms.setFuid(userId);
		Socket fse = socket.get(fuid+"");
		System.out.println("好友在线："+fse);
		
		if(fse!=null) {
			//在线发送消息
			this.sendMess(ms,fse);
		}else {		//这个好友不在线
			//好友不在线，那么就缓存这条消息
			//先判断有没有缓存的消息
			//缓存到这个好友的缓存消息队列里面
			LinkedList<Message> res = magQ.getUserMag(fuid);
			//！=null就是有了缓存的消息
			if(res!=null) {
				//设置一条消息
				//magQ.setUserMag(userId, ms);
				System.out.println("有消息缓存了");
				res.add(ms);
				
			}else {
				System.out.println("没有消息缓存");
				//没有缓存消息
				LinkedList<Message> li = new LinkedList<Message>();
				li.add(ms);
				//增加缓存队列
				magQ.setUserLinkedList(fuid, li);
			}
			System.out.println("---->缓存好友消息的数量："+ magQ.mess.get(fuid).size());
		}
	}
	
	/**
	 * 连接关闭后
	 * @param message
	 */
	@OnClose
	public void onClose(@PathParam("userId") String userId,Session session, CloseReason closeReason) {
		System.out.println(userId+"断开了连接");
		try {
			session.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		synchronized (Socket.class) {			
			socket.remove(userId);
		}
	}
	//发送消息
	public static void sendMess(Message ms,Socket fse) {
		String mess = JSON.toJSONString(ms);
		fse.session.getAsyncRemote().sendText(mess);
		System.out.println("发送消息成功！"+ms);
	}
	/**
	 * 连接出现异常时候触发
	 * @param throwable
	 */
	@OnError
	public void onError(@PathParam("userId") String userId,Throwable throwable) {
		synchronized (Socket.class) {			
			socket.remove(userId);
		}
	}
	
}
